package com.example.container;

import com.example.annotation.Bean;
import com.example.annotation.Configuration;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class CustomIocContainer {
    // 用Map存储Bean：key=Bean名称，value=Bean实例
    private final Map<String, Object> beanMap = new HashMap<>();

    // 构造方法：接收配置类，初始化容器
    public CustomIocContainer(Class<?>... configClasses) throws Exception {
        // 遍历所有配置类
        for (Class<?> configClass : configClasses) {
            // 校验：必须有@Configuration注解
            if (!configClass.isAnnotationPresent(Configuration.class)) {
                throw new RuntimeException("类 " + configClass.getName() + " 缺少@Configuration注解");
            }

            // 创建配置类实例（反射调用无参构造）
            Object configInstance = configClass.getDeclaredConstructor().newInstance();

            // 遍历配置类的所有方法
            Method[] methods = configClass.getDeclaredMethods();
            for (Method method : methods) {
                // 只处理带@Bean注解的方法
                if (method.isAnnotationPresent(Bean.class)) {
                    // 获取@Bean注解的value属性（Bean名称）
                    Bean beanAnnotation = method.getAnnotation(Bean.class);
                    String beanName = beanAnnotation.value();
                    // 若未指定名称，默认用方法名
                    if (beanName.isEmpty()) {
                        beanName = method.getName();
                    }

                    // 调用方法生成Bean实例（假设方法无参数）
                    Object beanInstance = method.invoke(configInstance);

                    // 存入容器
                    beanMap.put(beanName, beanInstance);
                    System.out.println("【容器初始化】加载Bean：" + beanName + "（类型：" + beanInstance.getClass().getSimpleName() + "）");
                }
            }
        }
        System.out.println("【容器初始化完成】共加载 " + beanMap.size() + " 个Bean");
    }

    // 根据名称获取Bean
    public Object getBean(String beanName) {
        if (!beanMap.containsKey(beanName)) {
            throw new RuntimeException("未找到Bean：" + beanName);
        }
        return beanMap.get(beanName);
    }

    // 根据类型获取Bean（简化版：假设同类型只有一个Bean）
    @SuppressWarnings("unchecked")
    public <T> T getBean(Class<T> type) {
        for (Object bean : beanMap.values()) {
            if (type.isInstance(bean)) {
                return (T) bean;
            }
        }
        throw new RuntimeException("未找到类型为 " + type.getName() + " 的Bean");
    }
}
